#pragma once
// 创建一个服务器类，负责完成相应的任务
#include "Socket.hpp"
#include <memory>
#include <signal.h>
#include <unistd.h>
#include <functional>

using callback_t = std::function<std::string(std::string &)>;

class Server
{
private:
    void HanderIO(std::shared_ptr<Socket> sockfd, InetAddr &addr)
    {
        std::string inbuffer;
        ssize_t n = _socket->Recv(&inbuffer);
        if (n > 0)
        {
            std::string send_str = _cb(inbuffer);
            sockfd->Send(send_str);
        }
        else if (n == 0)
        {
            LOG(LogLevel::WARNING) << addr.ToString() << " 读取完毕，退出";
        }
        else
        {
            LOG(LogLevel::ERROR) << addr.ToString() << " 读取失败，退出";
        }
        sockfd->Close();
    }

public:
    Server(uint16_t port, callback_t cb) : _port(port), _cb(cb), _socket(std::make_unique<TcpSocket>())
    {
        // 创建socket
        _socket->BuildSocket(port);
    }
    void Run()
    {
        // 所有服务器都是一个死循环
        while (true)
        {
            // 忽略子进程的退出信息
            signal(SIGCHLD, SIG_IGN);
            InetAddr clientaddr;
            auto sockfd = _socket->Accept(&clientaddr);
            // 为了不让程序阻塞住，我们创建子进程，让子进程执行相关的任务，父进程继续获取新的链接
            if (fork() == 0)
            {
                // 子进程完成后续操作
                // 子进程需要关闭监听sockfd
                _socket->Close();
                HanderIO(sockfd, clientaddr);
                exit(0);
            }
            // 父进程
            // 父进程需要关闭accept返回的sockfd
            sockfd->Close();
        }
    }
    ~Server() {}

private:
    uint16_t _port;
    callback_t _cb;
    std::unique_ptr<Socket> _socket; // 负责操作socket的指针，用基类指针访问子类的方式
};